#include "shift.hpp"
using namespace QuantumWalk;

typedef gen_op::ptr_t ptr_t;


template<typename T> void shift<T>::add_op(int i,matrix<T> m){
  std::pair<typename std::map<int,matrix<T> >::iterator,int> ret;
  ret=op_.insert(std::pair<int,matrix<T> > (i,m) );
  if(ret.second == false){
    std::cout<<"Permutation with key: "<<i<<" already exists."<<std::endl;
    std::cout<<"It will be modified from: "<<ret.first->second<< " to "
  	     <<m<<std::endl;
    ret.first->second=m;
  }
}

template<typename T> 
matrix<T> shift<T>::get_op(int i){
  typename std::map<int,matrix<T> >::iterator it;
  it=op_.find(i);
  if(it == op_.end()){
    std::cerr<<"Shift with internal degree "<<i<<" is not found. Exiting!"<<std::endl;
    exit(1);
  }
  return it->second;
}


template<typename T>
matrix<T> shift<T>::operator()(int i){
  return get_op(i);
}
template<typename T>
ptr_t shift<T>::pointer(){
  return this;
}

template<typename T>
const matrix<T> shift<T>::asmatrix(){
  int N=this->dimV_ * this->dimD_;
  matrix<T> ret(N,N,0);
  typename std::map<int,matrix<T> >::iterator it;
  for(it=op_.begin();it != op_.end();it++){
    int i=it->first;
    int r0=i * this->dimV_;
    int r1=(i+1) * this->dimV_; 
    matrix_range<matrix<T> > mr(ret,range (r0,r1),range (r0,r1) );
    mr=it->second;
  }
  return ret;
};

template class shift<std::complex<double> >;
